﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Reflection;
using System.Dynamic;
using DBA.Common;

namespace DBA.Data.ADO
{
    /// <summary>
    /// 采用了partial关键字，目前将DataAccessLibrary分成两个部分
    /// 数据访问函数库，sql语句部分
    /// </summary>
    public partial class DataAccessLibrary 
    {
        #region 钩子
        #region 设置存储过程的参数名称的前缀
        /// <summary>
        /// 设置存储过程的参数名称的前缀。
        /// </summary>
        /// <returns></returns>
        public virtual string ParameterPrefix()
        {
            return "@";
        }
        #endregion

        //#region 设置字段名左面的符号
        ///// <summary>
        ///// 设置字段名左面的符号。
        ///// </summary>
        ///// <returns></returns>
        //public virtual string ColumnLeft()
        //{
        //    return "[";
        //}
        //#endregion

        //#region 设置字段名右面的符号
        ///// <summary>
        ///// 设置字段名右面的符号。
        ///// </summary>
        ///// <returns></returns>
        //public virtual string ColumnRight()
        //{
        //    return "]";
        //}
        //#endregion

        #endregion

        //返回记录集部分

        #region ExecuteFillDataSet
        /// <summary>
        /// 运行SQL语句、参数化的SQL语句或者存储过程，返回DataSet。
        /// 可以传入多条查询语句，返回的DataSet里会有多个DataTable
        /// </summary>
        /// <param name="text">查询语句或者存储过程的名称。
        /// 比如select * from tableName1 select * from tableName2
        /// 或者 Proc_xxxGetDataSet
        /// </param>
        /// <returns>返回DataSet</returns>
        public virtual DataSet ExecuteFillDataSet(string text, bool isPro)
        {
            if (isPro)
            {
                SetStoredCommand(text);
            }
            else
            {
                //设置command
                SetCommand(text);
            }
           
            //创建一个DataAdapter，用于填充数据
            DbDataAdapter da = CommonFactory.CreateDataAdapter(Command, this.DatabaseProvider);
            
            //关联DataAdapter 和 Command
            da.SelectCommand = Command;
            try
            {
                DataSet ds = new DataSet();
                da.Fill(ds);                //打开数据库，填充数据
                return ds;
            }
            catch (Exception ex)
            {
                SetErrorMessage("ExecuteFillDataSet", text, ex.Message);	//处理错误
                return null;
            }
            finally
            {
                //自动关闭了，不用手动关闭。
                da.Dispose();
            }
        }
        #endregion

        #region ExecuteFillDataTable
        /// <summary>
        /// 运行SQL语句、参数化的SQL语句或者存储过程，返回DataTable记录集
        /// </summary>
        /// <param name="text">查询语句或者存储过程的名称。
        /// 比如select * from tableName1 
        /// 或者 Proc_xxxGetDataSet
        /// </param>
        /// <returns></returns>
        public virtual DataTable ExecuteFillDataTable(string text)
        {
            SetCommand(text);		//设置command
            DbDataAdapter da = CommonFactory.CreateDataAdapter(Command, this.DatabaseProvider);
            try
            {
                DataTable dt = new DataTable();

                //Command.Connection.Open();
                //dt.Load(Command.ExecuteReader());

                //if (!IsUseTrans)            //判断是否使用了事务，没有使用事务的情况下，才可以关闭连接
                //    Command.Connection.Close();

                da.Fill(dt);
                return dt;
            }
            catch (Exception ex)
            {
                SetErrorMessage("ExecuteFillDataTable", text, ex.Message + "<BR>ex:" + ex.ToString());	//处理错误
                return null;
            }
            finally
            {
                //if (!IsUseTrans)            //判断是否使用了事务，没有使用事务的情况下，才可以关闭连接
                //    Command.Connection.Close();

                ////自动关闭了，不用手动关闭。
                da.Dispose();
            }
          
        }

        public virtual IList<T> ExecuteFillObjects<T>(string text)
        {
            SetCommand(text);
            DbDataReader r = null;
            IList<T> reList = null;
            try
            {
                ConnectionOpen();
                r = Command.ExecuteReader();
                reList = ConvertHelper.DataReaderToList<T>(r);
            }
            catch (Exception ex)
            {
                SetErrorMessage("ExecuteFillObject<T>", text, ex.Message);	//处理错误
            }
            finally
            {
                if (r != null) r.Close();

                if (!IsUseTrans)        //判断是否使用了事务，没有使用事务的情况下，才可以关闭连接
                    Command.Connection.Close();
            }
            return reList;
        }

        //public dynamic ExecuteFillObject(string text)
        //{
        //    dynamic obj = new ExpandoObject();
        //    SetCommand(text);		//设置command
        //    DbDataReader r = null;
        //    try
        //    {
        //        ConnectionOpen();
        //        r = Command.ExecuteReader();
        //        if (r.Read())
        //        {
                    
        //            PropertyInfo[] pros = typeof(T).GetProperties();
        //            foreach (PropertyInfo pro in pros)
        //            {
        //                if (r[pro.Name].GetType() != typeof(DBNull))
        //                    //pro.SetValue(obj, r[pro.Name], null);
        //                    pro.FastSetValue<T>(obj, r[pro.Name]);
        //            }
        //        }

        //    }
        //    catch (Exception ex)
        //    {
        //        SetErrorMessage("ExecuteFillObject<T>", text, ex.Message);	//处理错误
        //    }
        //    finally
        //    {
        //        if (r != null) r.Close();

        //        if (!IsUseTrans)        //判断是否使用了事务，没有使用事务的情况下，才可以关闭连接
        //            Command.Connection.Close();
        //    }
        //    return obj;
        //}

        public virtual T ExecuteFillObject<T>(string text)
        {
            T obj = default(T);
            SetCommand(text);		//设置command
            DbDataReader r = null;
            try
            {
                //obj = System.Activator.CreateInstance<T>();
                ConnectionOpen();
                r = Command.ExecuteReader();
                if (r.Read())
                {
                    //PropertyInfo[] pros = typeof(T).GetProperties();
                    //foreach (PropertyInfo pro in pros)
                    //{
                    //    if (r[pro.Name].GetType() != typeof(DBNull))
                    //       //pro.SetValue(obj, r[pro.Name], null);
                    //         pro.FastSetValue<T>(obj, r[pro.Name]);
                    //}
                    obj = DynamicBuilder<T>.CreateBuilder(r).Build(r);
                }
                
            }
            catch (Exception ex)
            {
                SetErrorMessage("ExecuteFillObject<T>", text, ex.Message);	//处理错误
            }
            finally
            {
                if (r != null) r.Close();

                if (!IsUseTrans)        //判断是否使用了事务，没有使用事务的情况下，才可以关闭连接
                    Command.Connection.Close();
            }
            return obj;

        }
        #endregion

        #region ExecuteString
        /// <summary>
        /// 运行SQl语句返回第一条记录的第一个字段的值。
        /// </summary>
        /// <param name="text">查询语句。
        /// 比如select top 1 userName from tableName where ID=3。返回userName字段的内容。
        /// 适合字符串类型的字段</param>
        /// <returns></returns>
        public virtual string ExecuteString(string text)
        {
            return ExecuteString(text, "ExecuteString");
        }

        /// <summary>
        /// 运行SQl语句返回第一条记录的第一个字段的值。区分内部函数调用的情况
        /// </summary>
        /// <param name="text">SQL语句，或者参数化的SQL语句</param>
        /// <param name="functionName">函数名称。日志里需要这个名称，用于调试</param>
        /// <returns></returns>
        public virtual string ExecuteString(string text, string functionName)
        {
            SetCommand(text);		//设置command
            DbDataReader r = null;
            try
            {
                ConnectionOpen();
                r = Command.ExecuteReader(CommandBehavior.SingleRow);
                string re = "";
                if (r.Read())
                    re = r.GetValue(0).ToString();
                else
                    re = null;

                return re;

            }
            catch (Exception ex)
            {
                SetErrorMessage(functionName, text, ex.Message);	//处理错误
                return null;
            }
            finally
            {
                if (r != null) r.Close();

                if (!IsUseTrans)        //判断是否使用了事务，没有使用事务的情况下，才可以关闭连接
                    Command.Connection.Close();
            }
        }
        #endregion

        /// <summary>
        /// 得到第一条记录中的第一个对象
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public virtual object ExecuteScalar(string text)
        {
            SetCommand(text);		//设置command
            try
            {
                ConnectionOpen();
                return Command.ExecuteScalar();
            }
            catch (Exception ex)
            {
                SetErrorMessage("ExecuteScalar", text, ex.Message);	//处理错误
                return null;
            }
            finally
            {
                if (!IsUseTrans)        //判断是否使用了事务，没有使用事务的情况下，才可以关闭连接
                    Command.Connection.Close();
            }
        }

        /// <summary>
        /// 运行SQl语句返回第一条记录的第一个字段的值。区分内部函数调用的情况
        /// </summary>
        /// <param name="text">SQL语句，或者参数化的SQL语句</param>
        /// <returns></returns>
        public virtual T ExecuteScalar<T>(string text,string filedName)
        {
            SetCommand(text);		//设置command
            DbDataReader r = null;
            try
            {
                ConnectionOpen();
                T re = ReflectorHelper.CreateInstance<T>();
                object reValue = Command.ExecuteScalar();
                if (!VerificationHelper.IsNullOrEmpty(reValue))
                {
                    PropertyInfo[] pros = typeof(T).GetProperties();
                    foreach (PropertyInfo pro in pros)
                    {
                        if (pro.Name.ToLower()==filedName.ToLower())
                            //pro.SetValue(obj, r[pro.Name], null);
                            pro.FastSetValue<T>(re, reValue);
                    }
                }
                //T re  = (T)Convert.ChangeType(Command.ExecuteScalar(),   typeof(T));

                return re;

            }
            catch (Exception ex)
            {
                SetErrorMessage("ExecuteScalar<T>", text, ex.Message);	//处理错误
                return default(T);
            }
            finally
            {
                if (r != null) r.Close();

                if (!IsUseTrans)        //判断是否使用了事务，没有使用事务的情况下，才可以关闭连接
                    Command.Connection.Close();
            }
        }
    

        #region ExecuteStringsBySingleRow
        /// <summary>
        /// 运行SQl语句返回第一条记录的数组。返回字符串数组
        /// </summary>
        /// <param name="text">查询语句。比如select top 1 * from tableName</param>
        /// <returns></returns>
        public virtual string[] ExecuteStringsBySingleRow(string text)
        {
            //返回ID 传入查询语句，返回第一条记录的数组
            SetCommand(text);		//设置command
            DbDataReader r = null;
            try
            {
                this.ConnectionOpen();
                r = Command.ExecuteReader();
                string[] strValue = null;
                if (r.Read())
                {
                    int ArrLength = r.FieldCount;
                    strValue = new string[ArrLength];
                    for (int i = 0; i < ArrLength; i++)
                        strValue[i] = r.GetValue(i).ToString();
                }
                return strValue;
            }
            catch (Exception ex)
            {
                SetErrorMessage("ExecuteStringsBySingleRow", text, ex.Message);	//处理错误
                return null;
            }
            finally
            {
                if (r != null) r.Close();

                if (!IsUseTrans)    //判断是否使用了事务，没有使用事务的情况下，才可以关闭连接
                    Command.Connection.Close();
            }
        }
        #endregion

        #region ExecuteStringsByColumns
        /// <summary>
        /// 运行SQl语句返回每一条记录的第一个字段的值。返回字符串数组
        /// </summary>
        /// <param name="text">查询语句。比如select myName from tableName</param>
        /// <returns></returns>
        public virtual string[] ExecuteStringsByColumns(string text)
        {
            //传入查询语句，返回每条记录的第一的字段的值
            SetCommand(text);		//设置command
            DbDataReader r = null;
            try
            {
                this.ConnectionOpen();
                
                r = Command.ExecuteReader();
                //int i = 0;
                System.Collections.IList li = new System.Collections.ArrayList();
                while (r.Read())
                    li.Add(r[0].ToString());

                string[] strValue = new string[li.Count];
                li.CopyTo(strValue, 0);
                return strValue;

            }
            catch (Exception ex)
            {
                SetErrorMessage("ExecuteStringsByColumns", text , ex.Message);	//处理错误
                return null;
            }
            finally
            {
                if (r != null) r.Close();

                if (!IsUseTrans)            //判断是否使用了事务，没有使用事务的情况下，才可以关闭连接
                    Command.Connection.Close();

            }
        }
        #endregion

        //不返回记录集的
        //运行查询语句不返回记录集（无返回记录、检查持否存在指定的记录）

        #region ExecuteNonQuery 
        /// <summary>
        /// 运行SQL查询语句，不返回记录集。用于添加、修改、删除等操作
        /// </summary>
        /// <param name="sql">查询语句。比如insert into tableName 、update tableName...</param>
        /// <returns></returns>
        public virtual int ExecuteNonQuery(string sql)
        {
            return ExecuteNonQuery(sql, "ExecuteNonQuery" );
        }

         

        /// <summary>
        /// 运行SQL查询语句，不返回记录集。用于添加、修改、删除等操作。区分内部函数调用的情况
        /// </summary>
        /// <param name="sql">查询语句。比如insert into tableName 、update tableName...</param>
        /// <param name="functionName">函数名称，需要知道确切的调用的函数名称</param>
        /// <param name="isParameter">true：参数化的SQL；false：一般的SQL</param>
        /// <returns></returns>
        public virtual int ExecuteNonQuery(string sql, string functionName )
        {
            SetCommand(sql);		//设置command
            int reValue = 0;
            try
            {
                this.ConnectionOpen();
                _ExecuteRowCount = Command.ExecuteNonQuery();
                reValue = 1;

            }
            catch (Exception ex)
            {
                SetErrorMessage(functionName, sql, ex.Message);	//处理错误
            }
            finally
            {
                if (!IsUseTrans)            //判断是否使用了事务，没有使用事务的情况下，才可以关闭连接
                    Command.Connection.Close();
            }
            return reValue;
        }
        #endregion

        #region ExecuteStore
        public virtual int ExecuteStore(string sql)
        {
            return 0;
        }
        public virtual int ExecuteStore(string sql, string functionName)
        {
            return 0;
        }
        #endregion
    }
}
